Date: Sat Sep 7 13:39:10 2019
Scientist: Ran Yin
Sequencing (Waksman): Dibyendu Kumar
Statistics: Davit Sargsyan
Principal Investigator: Ah-Ng Kong
# Taxonomic Ranks:
# **K**ing **P**hillip **C**an n**O**t **F**ind **G**reen **S**ocks
# * Kingdom
# * Phylum
# * Class
# * Order
# * Family
# * Genus
# * Species
options(stringsAsFactors = FALSE,
scipen = 999)
# # Increase mmemory size to 64 Gb----
# invisible(utils::memory.limit(65536))
# str(knitr::opts_chunk$get())
# # NOTE: the below does not work!
# knitr::opts_chunk$set(echo = FALSE,
# message = FALSE,
# warning = FALSE,
# error = FALSE)
# require(knitr)
# require(kableExtra)
# require(phyloseq)
# require(shiny)
require(data.table)
require(ggplot2)
require(plotly)
require(DT)
source("source/functions_may2019.R")
# On Windows set multithread=FALSE----
mt <- TRUE
Introduction
C57BL/6 wild-type (WT) and Nrf-2 double-knock-out (KO -/-) mice were given 2-week microbiome stabilization process using AIN93M diet and 8 more weeks to treat with either AIN93M or AIN93M 5% PEITC diet. Fecal samples were collected weekly, immediately frozen in liquid nitrogen and stored at -80oC. Serum, cecal, colon epithelial and whole colon tissues at week 10 were also collected for further analyses. Baseline, week 1 and 4 fecal samples were selected for 16s rRNA sequencing.
This document examines results from the WT mice samples.
We will attampt to answer the following questions:
1. Did microbiome change over time?
2. Was microbiome affected by diet?
3. Was there a difference between the KO and WT?
4. If there was a change in microbiome composition, what functional changes did it carry? What are the essential functions of the bacteria affected by the treatment and how can this be shown in vivo (metabolites, inflammation markers, etc.)?
Data preprocessing
Raw Data
FastQ files were downloaded from Dr. Kumar’s DropBox. A total of 60 files (2 per sample, pair-ended) and 2 metadata files were downloaded.
Prune data
The OTUs were mapped to Bacteria (98.34%), Eukaryota (1.43%) and undefined (0.23%) kingdoms.
The total of 8,129 unique sequences were found. Out of those, 7,994 were mapped to bacterial genomes.
dim(ps_may2019@otu_table@.Data)
[1] 30 8129
# Remove OTU unmapped to Bacteria
ps0 <- subset_taxa(ps_may2019,
Kingdom == "Bacteria")
dim(ps0@otu_table@.Data)
[1] 30 7994
These belonged to 13 Phylum. 230 of the OTUs (or 2.88% of bacterial OTUs) could not be mapped to a Phyla and were removed from this analysis (with 7,764 OTUs left).
t2 <- data.table(table(tax_table(ps0)[, "Phylum"],
exclude = NULL))
t2$V1[is.na(t2$V1)] <- "Unknown"
setorder(t2, -N)
t2[, pct := N/sum(N)]
setorder(t2, -N)
colnames(t2) <- c("Phylum",
"Number of OTUs",
"Percent of OTUs")
datatable(t2,
rownames = FALSE,
caption = "Number of Bacterial OTUs by Phylum",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t2))) %>%
formatCurrency(columns = 2,
currency = "",
mark = ",",
digits = 0) %>%
formatPercentage(columns = 3,
digits = 2)
ps1 <- subset_taxa(ps0,
!is.na(Phylum))
dim(ps1@otu_table@.Data)
[1] 30 7764
Richness (Alpha diversity)
Shannon’s diversity index was calculated for each sample and ploted over time using the 7,764 from the 13 Phylum above.
ps0@sam_data$Diet_Week <- paste(samples$TREATMENT,
samples$WEEK,
sep = "_")
ps0@sam_data$ID <- substr(x = ps0@sam_data$SAMPLE_NAME,
start = 2,
stop = 3)
p1 <- plot_richness(ps0,
x = "Diet_Week",
measures = "Shannon") +
geom_line(aes(group = ID),
color = "black") +
geom_point(aes(fill = ID),
shape = 21,
size = 3,
color = "black") +
scale_x_discrete("") +
theme(axis.text.x = element_text(angle = 30,
hjust = 1,
vjust = 1))
ggplotly(p = p1,
tooltip = c("ID",
"value"))
p1 <- p1 + theme(legend.position = "none")
tiff(filename = "tmp/wt_shannon.tiff",
height = 4,
width = 5,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
tmp <- data.table(p1$data)
tmp[, delta := value[WEEK == "week 4"] -
value[WEEK == "week 0"],
by = ID]
tmp1 <- droplevels(unique(tmp[WEEK %in% c("week 0",
"week 4"),
c("value",
"WEEK",
"TREATMENT")]))
m1 <- lm(value ~ WEEK*TREATMENT,
data = tmp1)
print("Model1: Shannon's index by treatment and time")
[1] "Model1: Shannon's index by treatment and time"
anova(m1)
Analysis of Variance Table
Response: value
Df Sum Sq Mean Sq F value Pr(>F)
WEEK 1 0.03260 0.032600 0.9415 0.3463
TREATMENT 1 0.00184 0.001836 0.0530 0.8208
WEEK:TREATMENT 1 0.03978 0.039778 1.1487 0.2997
Residuals 16 0.55405 0.034628
tmp2 <- droplevels(unique(tmp[WEEK == "week 0",
c("delta",
"value",
"TREATMENT")]))
m2 <- lm(delta ~ TREATMENT,
data = tmp2)
print("Model2: Shannon's index differences (Week 4 - Week 0) by treatment")
[1] "Model2: Shannon's index differences (Week 4 - Week 0) by treatment"
anova(m2)
Analysis of Variance Table
Response: delta
Df Sum Sq Mean Sq F value Pr(>F)
TREATMENT 1 0.07956 0.079555 1.2057 0.3041
Residuals 8 0.52784 0.065981
m3 <- wilcox.test(delta ~ TREATMENT,
data = tmp2)
print("Model3: Wilcoxon test for Shannon's index differences (Week 4 - Week 0) by treatment")
[1] "Model3: Wilcoxon test for Shannon's index differences (Week 4 - Week 0) by treatment"
m3
Wilcoxon rank sum test
data: delta by TREATMENT
W = 7, p-value = 0.3095
alternative hypothesis: true location shift is not equal to 0
The results showed that in 4 out of 5 animals in the PEITC group diversity increased over the 4 weeks compared to the baseline. At the same time, only 2 out of 5 Control animals increased its microbial diversity in the same period of time. NOTE: there was no statistically significant difference between the treatment groups as well as over time (see results above).
OTU table (first 10 rows)
Total counts per sample (i.e. sequencing depth)
Relative abundance (%) at Phylum level
Remove phyla with relative abundance of >= 1% in less than 10% of samples.
t1 <- data.table(Phylum = ra_p$Phylum,
`Number of Samples` = rowSums(ra_p[, 2:ncol(ra_p)] >= 0.01))
t1$`Percent Samples` <- t1$`Number of Samples`/30
setorder(t1, -`Number of Samples`)
datatable(t1,
rownames = FALSE,
caption = "Taxonomic count table",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t1))) %>%
formatPercentage(columns = 3,
digits = 1)
Hence, only 6 out of 13 Phyla were studied in this analysis: Actinobacteria, Bacteroidetes, Firmicutes, Proteobacteria, Tenericutes and Verrucomicrobia. Relative abundance at the next taxonomic level (Class) was, therefore, computed relative to the sum of these 6 Phyla.
[1] "Bacteroidetes, Firmicutes, Proteobacteria, Verrucomicrobia, Actinobacteria, Tenericutes"
7,628 OTUs, down from 7,764 OTUs in the previous table.
Relative Abundance in Samples at Different Taxonomic Ranks
1. Class
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Treatment)) +
facet_wrap(~ Class,
scale = "free_y") +
geom_line() +
geom_point(aes(shape = Treatment,
color = Treatment),
size = 3,
alpha = 0.5) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_class_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)

p1 <- ggplot(mu,
aes(x = x,
y = Class,
color = Treatment,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_class_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
2. Order
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Treatment)) +
facet_wrap(~ Order,
scale = "free_y") +
geom_line() +
geom_point(aes(shape = Treatment,
color = Treatment),
size = 5,
alpha = 0.5)
print(p0)
p1 <- ggplot(mu,
aes(x = x,
y = Order,
fill = Treatment,
shape = Week)) +
# facet_wrap(~ Sex, nrow = 1) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)")
ggplotly(p1)
LS0tCnRpdGxlOiAiTnJmMiBCTDYgV2lsZC1UeXBlIChXVCkgUEVJVEMgMTZTIE1pY3JvYmlvbWUgRGF0YSBWaXN1YWxpemF0aW9uIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCkRhdGU6IGByIGRhdGUoKWAgICAgIApTY2llbnRpc3Q6IFtSYW4gWWluXShtYWlsdG86cnkxNDdAc2NhcmxldG1haWwucnV0Z2Vycy5lZHUpICAgICAgClNlcXVlbmNpbmcgKFdha3NtYW4pOiBbRGlieWVuZHUgS3VtYXJdKG1haWx0bzpka0B3YWtzbWFuLnJ1dGdlcnMuZWR1KSAgICAgIApTdGF0aXN0aWNzOiBbRGF2aXQgU2FyZ3N5YW5dKG1haWx0bzpzYXJnZGF2aWRAZ21haWwuY29tKSAgICAgIApQcmluY2lwYWwgSW52ZXN0aWdhdG9yOiBbQWgtTmcgS29uZ10obWFpbHRvOmtvbmd0QHBoYXJtYWN5LnJ1dGdlcnMuZWR1KSAKCmBgYHt9CiMgVGF4b25vbWljIFJhbmtzOgojICoqSyoqaW5nICoqUCoqaGlsbGlwICoqQyoqYW4gbioqTyoqdCAqKkYqKmluZCAqKkcqKnJlZW4gKipTKipvY2tzCiMgKiBLaW5nZG9tICAgICAgICAgICAgICAgIAojICogUGh5bHVtICAgICAgICAgICAgICAgICAgICAKIyAqIENsYXNzICAgICAgICAgICAgICAgICAgIAojICogT3JkZXIgICAgICAgICAgICAgICAgICAgCiMgKiBGYW1pbHkgICAgIAojICogR2VudXMgICAgIAojICogU3BlY2llcyAgCmBgYAoKYGBge3Igc2V0dXB9Cm9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAogICAgICAgIHNjaXBlbiA9IDk5OSkKCiMgIyBJbmNyZWFzZSBtbWVtb3J5IHNpemUgdG8gNjQgR2ItLS0tCiMgaW52aXNpYmxlKHV0aWxzOjptZW1vcnkubGltaXQoNjU1MzYpKQoKCiMgc3RyKGtuaXRyOjpvcHRzX2NodW5rJGdldCgpKQojICMgTk9URTogdGhlIGJlbG93IGRvZXMgbm90IHdvcmshCiMga25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgCiMgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwKIyAgICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLAojICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IEZBTFNFKQoKIyByZXF1aXJlKGtuaXRyKQojIHJlcXVpcmUoa2FibGVFeHRyYSkKIyByZXF1aXJlKHBoeWxvc2VxKQojIHJlcXVpcmUoc2hpbnkpCgpyZXF1aXJlKGRhdGEudGFibGUpCnJlcXVpcmUoZ2dwbG90MikKcmVxdWlyZShwbG90bHkpCnJlcXVpcmUoRFQpCgpzb3VyY2UoInNvdXJjZS9mdW5jdGlvbnNfbWF5MjAxOS5SIikKCiMgT24gV2luZG93cyBzZXQgbXVsdGl0aHJlYWQ9RkFMU0UtLS0tCm10IDwtIFRSVUUKYGBgCgojIEludHJvZHVjdGlvbgpDNTdCTC82IHdpbGQtdHlwZSAoV1QpIGFuZCBOcmYtMiBkb3VibGUta25vY2stb3V0IChLTyAtLy0pIG1pY2Ugd2VyZSBnaXZlbiAyLXdlZWsgbWljcm9iaW9tZSBzdGFiaWxpemF0aW9uIHByb2Nlc3MgdXNpbmcgQUlOOTNNIGRpZXQgYW5kIDggbW9yZSB3ZWVrcyB0byB0cmVhdCB3aXRoIGVpdGhlciBBSU45M00gb3IgQUlOOTNNIDUlIFBFSVRDIGRpZXQuIEZlY2FsIHNhbXBsZXMgd2VyZSBjb2xsZWN0ZWQgd2Vla2x5LCBpbW1lZGlhdGVseSBmcm96ZW4gaW4gbGlxdWlkIG5pdHJvZ2VuIGFuZCBzdG9yZWQgYXQgLTgwXm9eQy4gU2VydW0sIGNlY2FsLCBjb2xvbiBlcGl0aGVsaWFsIGFuZCB3aG9sZSBjb2xvbiB0aXNzdWVzIGF0IHdlZWsgMTAgd2VyZSBhbHNvIGNvbGxlY3RlZCBmb3IgZnVydGhlciBhbmFseXNlcy4gQmFzZWxpbmUsIHdlZWsgMSBhbmQgNCBmZWNhbCBzYW1wbGVzIHdlcmUgc2VsZWN0ZWQgZm9yIDE2cyByUk5BIHNlcXVlbmNpbmcuICAKICAKVGhpcyBkb2N1bWVudCBleGFtaW5lcyByZXN1bHRzIGZyb20gdGhlIFdUIG1pY2Ugc2FtcGxlcy4gIAogIApXZSB3aWxsIGF0dGFtcHQgdG8gYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOiAgCjEuIERpZCBtaWNyb2Jpb21lIGNoYW5nZSBvdmVyIHRpbWU/ICAKMi4gV2FzIG1pY3JvYmlvbWUgYWZmZWN0ZWQgYnkgZGlldD8gIAozLiBXYXMgdGhlcmUgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIEtPIGFuZCBXVD8gIAo0LiBJZiB0aGVyZSB3YXMgYSBjaGFuZ2UgaW4gbWljcm9iaW9tZSBjb21wb3NpdGlvbiwgd2hhdCBmdW5jdGlvbmFsIGNoYW5nZXMgZGlkIGl0IGNhcnJ5PyBXaGF0IGFyZSB0aGUgZXNzZW50aWFsIGZ1bmN0aW9ucyBvZiB0aGUgYmFjdGVyaWEgYWZmZWN0ZWQgYnkgdGhlIHRyZWF0bWVudCBhbmQgaG93IGNhbiB0aGlzIGJlIHNob3duIGluIHZpdm8gKG1ldGFib2xpdGVzLCBpbmZsYW1tYXRpb24gbWFya2VycywgZXRjLik/CgojIERhdGEgcHJlcHJvY2Vzc2luZwojIyBSYXcgRGF0YSAKRmFzdFEgZmlsZXMgd2VyZSBkb3dubG9hZGVkIGZyb20gW0RyLiBLdW1hcidzIERyb3BCb3hdKGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3NoL3NtOXRpbm0wZjVyNnkxdi9BQURqR1BSUk5pSU03ek1TZkFORGtRakZhP2RsPTApLiBBIHRvdGFsIG9mIDYwIGZpbGVzICgyIHBlciBzYW1wbGUsIHBhaXItZW5kZWQpIGFuZCAyIG1ldGFkYXRhIGZpbGVzIHdlcmUgZG93bmxvYWRlZC4KCiMjIFNjcmlwdApUaGlzIHNjcmlwdCAoKioqbnJmMnViaW9tZV9kYWRhMl9tYXkyMDE5X3YxLlJtZCoqKikgd2FzIGRldmVsb3BlZCB1c2luZyBbREFEQTIgUGlwZWxpbmUgVHV0b3JpYWwgKDEuMTIpXShodHRwczovL2JlbmpqbmViLmdpdGh1Yi5pby9kYWRhMi90dXRvcmlhbC5odG1sKSB3aXRoIHRpcHMgYW5kIHRyaWNrcyBmcm9tIHRoZSBbVW5pdmVyc2l0eSBvZiBNYXJ5bGFuZCBTaG9vbCBvZiBNZWRpY2luZSBJbnN0aXR1dGUgZm9yIEdlbm9tZSBTY2llbmNlcyAoSUdTKV0oaHR0cDovL3d3dy5pZ3MudW1hcnlsYW5kLmVkdS8pIFtNaWNyb2Jpb21lIEFuYWx5c2lzIFdvcmtzaG9wIChBcHJpbCA4LTExLCAyMDE5KV0oaHR0cDovL3d3dy5pZ3MudW1hcnlsYW5kLmVkdS9lZHVjYXRpb24vd2tzaHBfbWV0YWdlbm9tZS5waHApLiBUaGUgb3V0cHV0IG9mIHRoZSBEQURBMiBzY3JpcHQgKCoqKmRhdGFfbWF5MjAxOS9wc19tYXkyMDE5LlJEYXRhKioqKSBpcyBleHBsb3JlZCBpbiB0aGlzIGRvY3VtZW50LgoKIyBNZXRhIGRhdGE6IHNhbXBsZSBkZXNjcmlwdGlvbgpgYGB7ciBkYXRhfQojIExvYWQgZGF0YS0tLS0KIyBDb3VudHMKbG9hZCgiZGF0YV9tYXkyMDE5L3BzX21heTIwMTkuUkRhdGEiKQoKIyBUYXhvbm9teQpsb2FkKCJkYXRhX21heTIwMTkvdGF4YS5SRGF0YSIpCnRheGEgPC0gZGF0YS50YWJsZShzZXExNnMgPSByb3duYW1lcyh0YXhhKSwKICAgICAgICAgICAgICAgICAgIHRheGEpCgojIFNhbXBsZXMKc2FtcGxlcyA8LSBwc19tYXkyMDE5QHNhbV9kYXRhCmRhdGF0YWJsZShzYW1wbGVzLAogICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSBucm93KHNhbXBsZXMpKSkKYGBgCgojIFBydW5lIGRhdGEKVGhlIE9UVXMgd2VyZSBtYXBwZWQgdG8gQmFjdGVyaWEgKDk4LjM0JSksIEV1a2FyeW90YSAoMS40MyUpIGFuZCB1bmRlZmluZWQgKDAuMjMlKSBraW5nZG9tcy4gCgpgYGB7ciBjaGVja19tYXBwaW5nX2tpbmdkb20sIHdhcm5pbmcgPSBGQUxTRSwgZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CnQxIDwtIGRhdGEudGFibGUodGFibGUodGF4X3RhYmxlKHBzX21heTIwMTkpWywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIktpbmdkb20iXSwKICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlID0gTlVMTCkpCnQxJFYxW2lzLm5hKHQxJFYxKV0gPC0gIlVua25vd24iCgp0MVssIHBjdCA6PSBOL3N1bShOKV0Kc2V0b3JkZXIodDEsIC1OKQoKY29sbmFtZXModDEpIDwtIGMoIktpbmdkb20iLAogICAgICAgICAgICAgICAgICAiTnVtYmVyIG9mIE9UVXMiLAogICAgICAgICAgICAgICAgICAiUGVyY2VudCBvZiBPVFVzIikKZGF0YXRhYmxlKHQxLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiTnVtYmVyIG9mIE9UVXMgYnkgS2luZ2RvbSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gbnJvdyh0MSkpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gMiwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkgJT4lCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMywKICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCmBgYAoKVGhlIHRvdGFsIG9mIDgsMTI5IHVuaXF1ZSBzZXF1ZW5jZXMgd2VyZSBmb3VuZC4gT3V0IG9mIHRob3NlLCA3LDk5NCB3ZXJlIG1hcHBlZCB0byBiYWN0ZXJpYWwgZ2Vub21lcy4gCgpgYGB7ciBrZWVwX2JhY3RlcmlhfQpkaW0ocHNfbWF5MjAxOUBvdHVfdGFibGVALkRhdGEpCgojIFJlbW92ZSBPVFUgdW5tYXBwZWQgdG8gQmFjdGVyaWEKcHMwIDwtIHN1YnNldF90YXhhKHBzX21heTIwMTksIAogICAgICAgICAgICAgICAgICAgS2luZ2RvbSA9PSAiQmFjdGVyaWEiKQpkaW0ocHMwQG90dV90YWJsZUAuRGF0YSkKYGBgCiAgClRoZXNlIGJlbG9uZ2VkIHRvIDEzIFBoeWx1bS4gMjMwIG9mIHRoZSBPVFVzIChvciAyLjg4JSBvZiBiYWN0ZXJpYWwgT1RVcykgY291bGQgbm90IGJlIG1hcHBlZCB0byBhIFBoeWxhIGFuZCB3ZXJlIHJlbW92ZWQgZnJvbSB0aGlzIGFuYWx5c2lzICh3aXRoIDcsNzY0IE9UVXMgbGVmdCkuCgpgYGB7ciBwaHlsdW1fbWFwcGluZ30KdDIgPC0gZGF0YS50YWJsZSh0YWJsZSh0YXhfdGFibGUocHMwKVssICJQaHlsdW0iXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGUgPSBOVUxMKSkKdDIkVjFbaXMubmEodDIkVjEpXSA8LSAiVW5rbm93biIKc2V0b3JkZXIodDIsIC1OKQp0MlssIHBjdCA6PSBOL3N1bShOKV0Kc2V0b3JkZXIodDIsIC1OKQoKY29sbmFtZXModDIpIDwtIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgT1RVcyIsCiAgICAgICAgICAgICAgICAgICJQZXJjZW50IG9mIE9UVXMiKQoKZGF0YXRhYmxlKHQyLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiTnVtYmVyIG9mIEJhY3RlcmlhbCBPVFVzIGJ5IFBoeWx1bSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gbnJvdyh0MikpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gMiwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkgJT4lCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMywKICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCgpwczEgPC0gc3Vic2V0X3RheGEocHMwLCAKICAgICAgICAgICAgICAgICAgICFpcy5uYShQaHlsdW0pKQpkaW0ocHMxQG90dV90YWJsZUAuRGF0YSkKYGBgCgojIFJpY2huZXNzIChBbHBoYSBkaXZlcnNpdHkpClNoYW5ub24ncyBkaXZlcnNpdHkgaW5kZXggd2FzIGNhbGN1bGF0ZWQgZm9yIGVhY2ggc2FtcGxlIGFuZCBwbG90ZWQgb3ZlciB0aW1lIHVzaW5nIHRoZSA3LDc2NCBmcm9tIHRoZSAxMyBQaHlsdW0gYWJvdmUuCgpgYGB7ciByaWNobmVzcywgZmlnLndpZHRoID0gMTAsZmlnLmhlaWdodCA9IDV9CnBzMEBzYW1fZGF0YSREaWV0X1dlZWsgPC0gcGFzdGUoc2FtcGxlcyRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlcyRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIikKcHMwQHNhbV9kYXRhJElEIDwtIHN1YnN0cih4ID0gcHMwQHNhbV9kYXRhJFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9wID0gMykKcDEgPC0gcGxvdF9yaWNobmVzcyhwczAsCiAgICAgICAgICAgICAgICAgICAgeCA9ICJEaWV0X1dlZWsiLCAKICAgICAgICAgICAgICAgICAgICBtZWFzdXJlcyA9ICJTaGFubm9uIikgKwogICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IElEKSwKICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IElEKSwKICAgICAgICAgICAgIHNoYXBlID0gMjEsCiAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdCA9IDEpKQoKZ2dwbG90bHkocCA9IHAxLAogICAgICAgICB0b29sdGlwID0gYygiSUQiLAogICAgICAgICAgICAgICAgICAgICAidmFsdWUiKSkKCnAxIDwtIHAxICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3Rfc2hhbm5vbi50aWZmIiwKICAgICBoZWlnaHQgPSA0LAogICAgIHdpZHRoID0gNSwKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDEpCmdyYXBoaWNzLm9mZigpCmBgYAoKYGBge3IgdGVzdF9yaWNobmVzc30KdG1wIDwtIGRhdGEudGFibGUocDEkZGF0YSkKdG1wWywgZGVsdGEgOj0gdmFsdWVbV0VFSyA9PSAid2VlayA0Il0gLSAKICAgICAgdmFsdWVbV0VFSyA9PSAid2VlayAwIl0sCiAgICBieSA9IElEXQoKdG1wMSA8LSBkcm9wbGV2ZWxzKHVuaXF1ZSh0bXBbV0VFSyAlaW4lIGMoIndlZWsgMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3ZWVrIDQiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV0VFSyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSRUFUTUVOVCIpXSkpCm0xIDwtIGxtKHZhbHVlIH4gV0VFSypUUkVBVE1FTlQsCiAgICAgICAgIGRhdGEgPSB0bXAxKQpwcmludCgiTW9kZWwxOiBTaGFubm9uJ3MgaW5kZXggYnkgdHJlYXRtZW50IGFuZCB0aW1lIikKYW5vdmEobTEpCgp0bXAyIDwtIGRyb3BsZXZlbHModW5pcXVlKHRtcFtXRUVLID09ICJ3ZWVrIDAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiZGVsdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSRUFUTUVOVCIpXSkpCm0yIDwtIGxtKGRlbHRhIH4gVFJFQVRNRU5ULAogICAgICAgICBkYXRhID0gdG1wMikKcHJpbnQoIk1vZGVsMjogU2hhbm5vbidzIGluZGV4IGRpZmZlcmVuY2VzIChXZWVrIDQgLSBXZWVrIDApIGJ5IHRyZWF0bWVudCIpCmFub3ZhKG0yKQoKbTMgPC0gd2lsY294LnRlc3QoZGVsdGEgfiBUUkVBVE1FTlQsCiAgICAgICAgICAgIGRhdGEgPSB0bXAyKQpwcmludCgiTW9kZWwzOiBXaWxjb3hvbiB0ZXN0IGZvciBTaGFubm9uJ3MgaW5kZXggZGlmZmVyZW5jZXMgKFdlZWsgNCAtIFdlZWsgMCkgYnkgdHJlYXRtZW50IikKbTMKYGBgCiAgClRoZSByZXN1bHRzIHNob3dlZCB0aGF0IGluIDQgb3V0IG9mIDUgYW5pbWFscyBpbiB0aGUgUEVJVEMgZ3JvdXAgZGl2ZXJzaXR5IGluY3JlYXNlZCBvdmVyIHRoZSA0IHdlZWtzIGNvbXBhcmVkIHRvIHRoZSBiYXNlbGluZS4gQXQgdGhlIHNhbWUgdGltZSwgb25seSAyIG91dCBvZiA1IENvbnRyb2wgYW5pbWFscyBpbmNyZWFzZWQgaXRzIG1pY3JvYmlhbCBkaXZlcnNpdHkgaW4gdGhlIHNhbWUgcGVyaW9kIG9mIHRpbWUuIE5PVEU6IHRoZXJlIHdhcyBubyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHJlYXRtZW50IGdyb3VwcyBhcyB3ZWxsIGFzIG92ZXIgdGltZSAoc2VlIHJlc3VsdHMgYWJvdmUpLiAgCiAgCiMgT1RVIHRhYmxlIChmaXJzdCAxMCByb3dzKQpgYGB7ciBvdHVfdGFibGUsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQpvdHUgPC0gZGF0YS50YWJsZShwczBAdGF4X3RhYmxlQC5EYXRhLAogICAgICAgICAgICAgICAgICB0KHBzMEBvdHVfdGFibGVALkRhdGEpKQpkYXRhdGFibGUoaGVhZChvdHUsIDEwKSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDc6MzYsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDApCmBgYAoKIyBUb3RhbCBjb3VudHMgcGVyIHNhbXBsZSAoaS5lLiBzZXF1ZW5jaW5nIGRlcHRoKQpgYGB7ciBUYXgsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xMCxmaWcuaGVpZ2h0PTV9CnQxIDwtIGNvbFN1bXMob3R1WywgNzpuY29sKG90dSldKQp0MSA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gbmFtZXModDEpLAogICAgICAgICAgICAgICAgIFRvdGFsID0gdDEpCgp0bXAgPC0gZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHNhbXBsZXMkU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgIFRSRUFUTUVOVCA9IHNhbXBsZXMkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICBXRUVLID0gc2FtcGxlcyRXRUVLKQoKdDEgPC0gbWVyZ2UodG1wLAogICAgICAgICAgICB0MSwKICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQoKcDEgPC0gZ2dwbG90KHQxLAogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICB5ID0gVG90YWwsCiAgICAgICAgICAgICAgICAgZmlsbCA9IFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICBjb2xvdXIgPSBXRUVLKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiU2FtcGxlIE5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJOdW1iZXIgb2YgUmVhZHMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgiR3JvdXAiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKSAKZ2dwbG90bHkocDEpCmBgYAoKIyBDb3VudHMgYXQgUGh5bHVtIGxldmVsCmBgYHtyIGNvdW50c19wLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KY291bnRzX3AgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiUGh5bHVtIikKc2V0b3JkZXIoY291bnRzX3AsIC1gMEExYCkKZGF0YXRhYmxlKGNvdW50c19wLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gbnJvdyhjb3VudHNfcCkpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gMjpuY29sKGNvdW50c19wKSwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkKYGBgCgojIFJlbGF0aXZlIGFidW5kYW5jZSAoJSkgYXQgUGh5bHVtIGxldmVsCmBgYHtyIHJhX3AsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQpyYV9wIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50cyA9IGNvdW50c19wLAogICAgICAgICAgICAgICAgICAgICAgIHBjdCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0ID0gNCkKCmRhdGF0YWJsZShyYV9wLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gbnJvdyhyYV9wKSkpICU+JQogIGZvcm1hdFBlcmNlbnRhZ2UoY29sdW1ucyA9IDI6bmNvbChjb3VudHNfcCksCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQpgYGAKClJlbW92ZSBwaHlsYSB3aXRoIHJlbGF0aXZlIGFidW5kYW5jZSBvZiA+PSAxJSBpbiBsZXNzIHRoYW4gMTAlIG9mIHNhbXBsZXMuCgpgYGB7ciBwcmV2X3B9CnQxIDwtIGRhdGEudGFibGUoUGh5bHVtID0gcmFfcCRQaHlsdW0sCiAgICAgICAgICAgICAgICAgYE51bWJlciBvZiBTYW1wbGVzYCA9IHJvd1N1bXMocmFfcFssIDI6bmNvbChyYV9wKV0gPj0gMC4wMSkpCnQxJGBQZXJjZW50IFNhbXBsZXNgIDwtICB0MSRgTnVtYmVyIG9mIFNhbXBsZXNgLzMwCgpzZXRvcmRlcih0MSwgLWBOdW1iZXIgb2YgU2FtcGxlc2ApCmRhdGF0YWJsZSh0MSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3codDEpKSkgJT4lCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMywKICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDEpCmBgYAoKSGVuY2UsIG9ubHkgNiBvdXQgb2YgMTMgUGh5bGEgd2VyZSBzdHVkaWVkIGluIHRoaXMgYW5hbHlzaXM6IEFjdGlub2JhY3RlcmlhLCBCYWN0ZXJvaWRldGVzLCBGaXJtaWN1dGVzLCBQcm90ZW9iYWN0ZXJpYSwgVGVuZXJpY3V0ZXMgYW5kIFZlcnJ1Y29taWNyb2JpYS4gUmVsYXRpdmUgYWJ1bmRhbmNlIGF0IHRoZSBuZXh0IHRheG9ub21pYyBsZXZlbCAoQ2xhc3MpIHdhcywgdGhlcmVmb3JlLCBjb21wdXRlZCByZWxhdGl2ZSB0byB0aGUgc3VtIG9mIHRoZXNlIDYgUGh5bGEuCgpgYGB7ciBrZWVwXzZfcGh5bGEsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQprZWVwX3AgPC0gdDEkUGh5bHVtW3QxJGBQZXJjZW50IFNhbXBsZXNgID49IDAuMV0KcGFzdGUwKGtlZXBfcCwgY29sbGFwc2UgPSAiLCAiKQoKcHMxIDwtIHN1YnNldF90YXhhKHBzMCwgCiAgICAgICAgICAgICAgICAgICBQaHlsdW0gJWluJSBrZWVwX3AgKQpvdHUxIDwtIGRhdGEudGFibGUocHMxQHRheF90YWJsZUAuRGF0YSwKICAgICAgICAgICAgICAgICAgIHQocHMxQG90dV90YWJsZUAuRGF0YSkpCgpkYXRhdGFibGUoaGVhZChvdHUxLCAxMCksCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSAxMCkpICU+JQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA3Om5jb2wob3R1MSksCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDApCmBgYAoKNyw2MjggT1RVcywgZG93biBmcm9tIDcsNzY0IE9UVXMgaW4gdGhlIHByZXZpb3VzIHRhYmxlLgoKCiMgUmVsYXRpdmUgQWJ1bmRhbmNlIGluIFNhbXBsZXMgYXQgRGlmZmVyZW50IFRheG9ub21pYyBSYW5rcwojIyAxLiBDbGFzcwpgYGB7ciBjb3VudHNfYywgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9Nn0KY291bnRzX2MgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2dyX2J5ID0gIkNsYXNzIikKcmFfYyA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfYykKCnRheC5yYW5rcyA8LSB1bmlxdWUob3R1MVssIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsYXNzIildKQoKcmFfYyA8LSBtZXJnZSh0YXgucmFua3MsCiAgICAgICAgICAgICAgcmFfYywKICAgICAgICAgICAgICBieSA9ICJDbGFzcyIpCgp0b3RhbCA8LSByb3dTdW1zKHJhX2NbLCAzOm5jb2wocmFfYyldKQoKcmFfYyRDbGFzcyA8LSBmYWN0b3IocmFfYyRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gcmFfYyRDbGFzc1tvcmRlcih0b3RhbCldKQoKcmFfYyRQaHlsdW0gPC0gZmFjdG9yKHJhX2MkUGh5bHVtLAogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gdW5pcXVlKHJhX2MkUGh5bHVtW29yZGVyKHRvdGFsKV0pKQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9jLAogICAgICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSAxOjIsCiAgICAgICAgICAgICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gMzpuY29sKGNvdW50c19jKSwKICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwKICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5uYW1lID0gIlJBIikKCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc2FtcGxlcyRTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgV0VFSyA9IHNhbXBsZXMkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgVFJFQVRNRU5UID0gc2FtcGxlcyRUUkVBVE1FTlQpLAogICAgICAgICAgICAgdG1wLAogICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQoKIyBQbG90IHNhbXBsZXMKcDEgPC0gZ2dwbG90KHRtcCwKICAgICAgICAgICAgIGFlcyh4ID0gU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgeSA9IFJBLAogICAgICAgICAgICAgICAgIGZpbGwgPSBDbGFzcywKICAgICAgICAgICAgICAgICBjb2xvciA9IFBoeWx1bSkpICsKICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLAogICAgICAgICAgICAgbnJvdyA9IDMpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQpnZ3Bsb3RseShwMSkKYGBgCgpgYGB7ciBtZWFuc19jLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX2MsCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzYW1wbGVzLAogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpCgptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgPSBscmEkQ2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSAibWVhbiIpKQptdVssIHRvdGFsIDo9IHN1bSh4KSwKICAgYnkgPSAiQ2xhc3MiXQp1bCA8LSB1bmlxdWUobXVbLCBjKCJDbGFzcyIsIAogICAgICAgICAgICAgICAgICAgICJ0b3RhbCIpXSkKdWwgPC0gdWxbb3JkZXIodG90YWwpLF0KbXUkQ2xhc3MgPC0gZmFjdG9yKG11JENsYXNzLAogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRDbGFzcykKbXUkdG90YWwgPC0gTlVMTAoKZGF0YXRhYmxlKG11LAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gbnJvdyhtdSksCiAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IGxpc3QobGlzdCgzLCAnZGVzYycpKSkpCmBgYAoKCmBgYHtyIG1lYW5zX2NfcDAsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA1fQpwMCA8LSBnZ3Bsb3QobXUsCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssCiAgICAgICAgICAgICAgICAgeSA9IHgsCiAgICAgICAgICAgICAgICAgZ3JvdXAgPSBUcmVhdG1lbnQpKSArCiAgZmFjZXRfd3JhcCh+IENsYXNzLAogICAgICAgICAgICAgc2NhbGUgPSAiZnJlZV95IikgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICBjb2xvciA9IFRyZWF0bWVudCksCiAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKwogIHNjYWxlX3lfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpCgp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9jbGFzc19vdmVyX3RpbWUudGlmZiIsCiAgICAgaGVpZ2h0ID0gNSwKICAgICB3aWR0aCA9IDcsCiAgICAgdW5pdHMgPSAiaW4iLAogICAgIHJlcyA9IDYwMCwKICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpCnByaW50KHAwKQpncmFwaGljcy5vZmYoKQoKcHJpbnQocDApCmBgYAoKCmBgYHtyIG1lYW5zX2NfcDEsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA2fQpwMSA8LSBnZ3Bsb3QobXUsCiAgICAgICAgICAgICBhZXMoeCA9IHgsCiAgICAgICAgICAgICAgICAgeSA9IENsYXNzLAogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJlYXRtZW50LAogICAgICAgICAgICAgICAgIHNoYXBlID0gV2VlaykpICsKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLAogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIHNjYWxlX3hfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikKCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X2NsYXNzX3JhLnRpZmYiLAogICAgIGhlaWdodCA9IDQsCiAgICAgd2lkdGggPSA3LAogICAgIHVuaXRzID0gImluIiwKICAgICByZXMgPSA2MDAsCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQpwcmludChwMSkKZ3JhcGhpY3Mub2ZmKCkKCmdncGxvdGx5KHAxKQpgYGAKCiMjIDIuIE9yZGVyCmBgYHtyIGNvdW50c19vLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSxmaWcud2lkdGg9MTAsZmlnLmhlaWdodD02fQpjb3VudHNfbyA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiT3JkZXIiKQpyYV9vIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19vKQoKdGF4LnJhbmtzIDwtIHVuaXF1ZShvdHUxWywgYygiUGh5bHVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3JkZXIiKV0pCgpyYV9vIDwtIG1lcmdlKHRheC5yYW5rcywKICAgICAgICAgICAgICByYV9vLAogICAgICAgICAgICAgIGJ5ID0gIk9yZGVyIikKCnRvdGFsIDwtIHJvd1N1bXMocmFfb1ssIDM6bmNvbChyYV9vKV0pCgpyYV9vJE9yZGVyIDwtIGZhY3RvcihyYV9vJE9yZGVyLAogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9vJE9yZGVyW29yZGVyKHRvdGFsKV0pCgpyYV9vJFBoeWx1bSA8LSBmYWN0b3IocmFfbyRQaHlsdW0sCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfbyRQaHlsdW1bb3JkZXIodG90YWwpXSkpCnRtcCA8LSBtZWx0LmRhdGEudGFibGUoZGF0YSA9IHJhX28sCiAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IDE6MiwKICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX28pLAogICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiU0FNUExFX05BTUUiLAogICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLm5hbWUgPSAiUkEiKQoKdG1wIDwtIG1lcmdlKGRhdGEudGFibGUoU0FNUExFX05BTUUgPSBzYW1wbGVzJFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICBXRUVLID0gc2FtcGxlcyRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzYW1wbGVzJFRSRUFUTUVOVCksCiAgICAgICAgICAgICB0bXAsCiAgICAgICAgICAgICBieSA9ICJTQU1QTEVfTkFNRSIpCgojIFBsb3Qgc2FtcGxlcwpwMSA8LSBnZ3Bsb3QodG1wLAogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICB5ID0gUkEsCiAgICAgICAgICAgICAgICAgZmlsbCA9IE9yZGVyLAogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKwogIGZhY2V0X3dyYXAofiBXRUVLICsgVFJFQVRNRU5ULAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWVfeCIsCiAgICAgICAgICAgICBucm93ID0gMykgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpCmdncGxvdGx5KHAxKQpgYGAKCmBgYHtyIG1lYW5zX28sIGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmxyYSA8LSByYV9tZWx0KHJhID0gcmFfbywKICAgICAgICAgICAgICAgc2FtcGxlcyA9IHNhbXBsZXMsCiAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lID0gIlNBTVBMRV9OQU1FIikKCm11IDwtIGRhdGEudGFibGUoYWdncmVnYXRlKGxyYSRSQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBsaXN0KFdlZWsgPSBscmEkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcmRlciA9IGxyYSRPcmRlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTiA9ICJtZWFuIikpCm11WywgdG90YWwgOj0gc3VtKHgpLAogICBieSA9ICJPcmRlciJdCnVsIDwtIHVuaXF1ZShtdVssIGMoIk9yZGVyIiwgCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQptdSRPcmRlciA8LSBmYWN0b3IobXUkT3JkZXIsCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJE9yZGVyKQptdSR0b3RhbCA8LSBOVUxMCgpkYXRhdGFibGUobXUsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KG11KSwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkKYGBgCgpgYGB7ciBtZWFuc19vX3AwLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDV9CnAwIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0gV2VlaywKICAgICAgICAgICAgICAgICB5ID0geCwKICAgICAgICAgICAgICAgICBncm91cCA9IFRyZWF0bWVudCkpICsKICBmYWNldF93cmFwKH4gT3JkZXIsCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gVHJlYXRtZW50LAogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJlYXRtZW50KSwKICAgICAgICAgICAgIHNpemUgPSA1LAogICAgICAgICAgICAgYWxwaGEgPSAwLjUpCnByaW50KHAwKQpgYGAKCmBgYHtyIG1lYW5zX29fcDEsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gMTB9CnAxIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0geCwKICAgICAgICAgICAgICAgICB5ID0gT3JkZXIsCiAgICAgICAgICAgICAgICAgZmlsbCA9IFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgIyBmYWNldF93cmFwKH4gU2V4LCBucm93ID0gMSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikKZ2dwbG90bHkocDEpCmBgYAoKIyBTZXNzaW9uIEluZm9ybWF0aW9uCmBgYHtyIGluZm8sZXZhbD1UUlVFfQpzZXNzaW9uSW5mbygpCmBgYA==